{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "os.environ['CUDA_VISIBLE_DEVICES'] = '0'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/husein/.local/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:516: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:517: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:518: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:519: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:520: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:525: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:541: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:542: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:543: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:544: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:545: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n",
      "/home/husein/.local/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:550: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "\n",
    "with open('train-test.json') as fopen:\n",
    "    dataset = json.load(fopen)\n",
    "    \n",
    "with open('dictionary.json') as fopen:\n",
    "    dictionary = json.load(fopen)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_X = dataset['train_X']\n",
    "train_Y = dataset['train_Y']\n",
    "test_X = dataset['test_X']\n",
    "test_Y = dataset['test_Y']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_keys(['from', 'to'])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dictionary.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "dictionary_from = dictionary['from']['dictionary']\n",
    "rev_dictionary_from = dictionary['from']['rev_dictionary']\n",
    "\n",
    "dictionary_to = dictionary['to']['dictionary']\n",
    "rev_dictionary_to = dictionary['to']['rev_dictionary']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "GO = dictionary_from['GO']\n",
    "PAD = dictionary_from['PAD']\n",
    "EOS = dictionary_from['EOS']\n",
    "UNK = dictionary_from['UNK']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Rachel Pike : The science behind a climate headline EOS'"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "for i in range(len(train_X)):\n",
    "    train_X[i] += ' EOS'\n",
    "    \n",
    "train_X[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'How can I speak in <NUM> minutes about the bonds of women over three generations , about how the astonishing strength of those bonds took hold in the life of a four - year - old girl huddled with her young sister , her mother and her grandmother for five days and nights in a small boat in the China Sea more than <NUM> years ago , bonds that took hold in the life of that small girl and never let go - - that small girl now living in San Francisco and speaking to you today ? EOS'"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "for i in range(len(test_X)):\n",
    "    test_X[i] += ' EOS'\n",
    "    \n",
    "test_X[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "from tensorflow.python.util import nest\n",
    "from tensorflow.python.layers.core import Dense\n",
    "\n",
    "def gnmt_residual_fn(inputs, outputs):\n",
    "    def split_input(inp, out):\n",
    "        out_dim = out.get_shape().as_list()[-1]\n",
    "        inp_dim = inp.get_shape().as_list()[-1]\n",
    "        return tf.split(inp, [out_dim, inp_dim - out_dim], axis=-1)\n",
    "    actual_inputs, _ = nest.map_structure(split_input, inputs, outputs)\n",
    "\n",
    "    def assert_shape_match(inp, out):\n",
    "        inp.get_shape().assert_is_compatible_with(out.get_shape())\n",
    "    nest.assert_same_structure(actual_inputs, outputs)\n",
    "    nest.map_structure(assert_shape_match, actual_inputs, outputs)\n",
    "    return nest.map_structure(lambda inp, out: inp + out, actual_inputs, outputs)\n",
    "\n",
    "class GNMTAttentionMultiCell(tf.nn.rnn_cell.MultiRNNCell):\n",
    "\n",
    "    def __init__(self, attention_cell, cells, use_new_attention=True):\n",
    "        cells = [attention_cell] + cells\n",
    "        self.use_new_attention = use_new_attention\n",
    "        super(GNMTAttentionMultiCell, self).__init__(\n",
    "            cells, state_is_tuple=True)\n",
    "\n",
    "    def __call__(self, inputs, state, scope=None):\n",
    "        \"\"\"Run the cell with bottom layer's attention copied to all upper layers.\"\"\"\n",
    "        if not nest.is_sequence(state):\n",
    "            raise ValueError(\n",
    "                \"Expected state to be a tuple of length %d, but received: %s\"\n",
    "                % (len(self.state_size), state))\n",
    "\n",
    "        with tf.variable_scope(scope or \"multi_rnn_cell\"):\n",
    "            new_states = []\n",
    "\n",
    "            with tf.variable_scope(\"cell_0_attention\"):\n",
    "                attention_cell = self._cells[0]\n",
    "                attention_state = state[0]\n",
    "                cur_inp, new_attention_state = attention_cell(\n",
    "                    inputs, attention_state)\n",
    "                new_states.append(new_attention_state)\n",
    "\n",
    "            for i in range(1, len(self._cells)):\n",
    "                with tf.variable_scope(\"cell_%d\" % i):\n",
    "                    cell = self._cells[i]\n",
    "                    cur_state = state[i]\n",
    "\n",
    "                    if self.use_new_attention:\n",
    "                        cur_inp = tf.concat(\n",
    "                            [cur_inp, new_attention_state.attention], -1)\n",
    "                    else:\n",
    "                        cur_inp = tf.concat(\n",
    "                            [cur_inp, attention_state.attention], -1)\n",
    "\n",
    "                    cur_inp, new_state = cell(cur_inp, cur_state)\n",
    "                    new_states.append(new_state)\n",
    "\n",
    "        return cur_inp, tuple(new_states)\n",
    "\n",
    "class Translator:\n",
    "    def __init__(self, size_layer, num_layers, embedded_size,\n",
    "                 from_dict_size, to_dict_size, learning_rate, beam_width = 5):\n",
    "        \n",
    "        def cells(size,reuse=False):\n",
    "            return tf.nn.rnn_cell.GRUCell(size,reuse=reuse)\n",
    "        \n",
    "        self.X = tf.placeholder(tf.int32, [None, None])\n",
    "        self.Y = tf.placeholder(tf.int32, [None, None])\n",
    "        self.X_seq_len = tf.count_nonzero(self.X, 1, dtype=tf.int32)\n",
    "        self.Y_seq_len = tf.count_nonzero(self.Y, 1, dtype=tf.int32)\n",
    "        batch_size = tf.shape(self.X)[0]\n",
    "        \n",
    "        encoder_embeddings = tf.Variable(tf.random_uniform([from_dict_size, embedded_size], -1, 1))\n",
    "        decoder_embeddings = tf.Variable(tf.random_uniform([to_dict_size, embedded_size], -1, 1))\n",
    "        encoder_embedded = tf.nn.embedding_lookup(encoder_embeddings, self.X)\n",
    "        main = tf.strided_slice(self.Y, [0, 0], [batch_size, -1], [1, 1])\n",
    "        decoder_input = tf.concat([tf.fill([batch_size, 1], GO), main], 1)\n",
    "        decoder_embedded = tf.nn.embedding_lookup(encoder_embeddings, decoder_input)\n",
    "        \n",
    "        num_residual_layer = num_layers - 2\n",
    "        num_bi_layer = 1\n",
    "        num_ui_layer = num_layers - num_bi_layer\n",
    "\n",
    "        for n in range(num_bi_layer):\n",
    "            (out_fw, out_bw), (state_fw, state_bw) = tf.nn.bidirectional_dynamic_rnn(\n",
    "                cell_fw = cells(size_layer),\n",
    "                cell_bw = cells(size_layer),\n",
    "                inputs = encoder_embedded,\n",
    "                sequence_length = self.X_seq_len,\n",
    "                dtype = tf.float32,\n",
    "                scope = 'bidirectional_rnn_%d'%(n))\n",
    "            encoder_embedded = tf.concat((out_fw, out_bw), 2)\n",
    "        \n",
    "        gru_cells = tf.nn.rnn_cell.MultiRNNCell([cells(size_layer) for _ in range(num_ui_layer)])\n",
    "        encoder_outputs, encoder_state = tf.nn.dynamic_rnn(\n",
    "                gru_cells,\n",
    "                encoder_embedded,\n",
    "                dtype=tf.float32,\n",
    "                sequence_length=self.X_seq_len)\n",
    "        \n",
    "        encoder_state = (state_bw,) + (\n",
    "                (encoder_state,) if num_ui_layer == 1 else encoder_state)\n",
    "        \n",
    "        decoder_cells = []\n",
    "        for n in range(num_layers):\n",
    "            cell = cells(size_layer)\n",
    "            if (n >= num_layers - num_residual_layer):\n",
    "                cell = tf.nn.rnn_cell.ResidualWrapper(cell, residual_fn = gnmt_residual_fn)\n",
    "            decoder_cells.append(cell)\n",
    "        attention_cell = decoder_cells.pop(0)\n",
    "        to_dense = tf.layers.Dense(to_dict_size)\n",
    "        \n",
    "        with tf.variable_scope('decode'):\n",
    "            attention_mechanism = tf.contrib.seq2seq.BahdanauAttention(\n",
    "                num_units = size_layer, \n",
    "                memory = encoder_outputs,\n",
    "                memory_sequence_length = self.X_seq_len)\n",
    "            att_cell = tf.contrib.seq2seq.AttentionWrapper(\n",
    "                cell = attention_cell,\n",
    "                attention_mechanism = attention_mechanism,\n",
    "                attention_layer_size = None,\n",
    "                alignment_history = True,\n",
    "                output_attention = False)\n",
    "            gcell = GNMTAttentionMultiCell(att_cell, decoder_cells)\n",
    "            \n",
    "            self.initial_state = tuple(\n",
    "                zs.clone(cell_state=es)\n",
    "                if isinstance(zs, tf.contrib.seq2seq.AttentionWrapperState) else es\n",
    "                for zs, es in zip(\n",
    "                    gcell.zero_state(batch_size, dtype=tf.float32), encoder_state))\n",
    "            \n",
    "            training_helper = tf.contrib.seq2seq.TrainingHelper(\n",
    "                decoder_embedded,\n",
    "                self.Y_seq_len,\n",
    "                time_major = False\n",
    "            )\n",
    "            training_decoder = tf.contrib.seq2seq.BasicDecoder(\n",
    "                cell = gcell,\n",
    "                helper = training_helper,\n",
    "                initial_state = self.initial_state,\n",
    "                output_layer = to_dense)\n",
    "            training_decoder_output, _, _ = tf.contrib.seq2seq.dynamic_decode(\n",
    "                decoder = training_decoder,\n",
    "                impute_finished = True,\n",
    "                maximum_iterations = tf.reduce_max(self.Y_seq_len))\n",
    "            self.training_logits = training_decoder_output.rnn_output\n",
    "            \n",
    "        with tf.variable_scope('decode', reuse=True):\n",
    "            encoder_out_tiled = tf.contrib.seq2seq.tile_batch(encoder_outputs, beam_width)\n",
    "            encoder_state_tiled = tf.contrib.seq2seq.tile_batch(encoder_state, beam_width)\n",
    "            X_seq_len_tiled = tf.contrib.seq2seq.tile_batch(self.X_seq_len, beam_width)\n",
    "            \n",
    "            attention_mechanism = tf.contrib.seq2seq.BahdanauAttention(\n",
    "                num_units = size_layer, \n",
    "                memory = encoder_out_tiled,\n",
    "                memory_sequence_length = X_seq_len_tiled)\n",
    "            att_cell = tf.contrib.seq2seq.AttentionWrapper(\n",
    "                cell = attention_cell,\n",
    "                attention_mechanism = attention_mechanism,\n",
    "                attention_layer_size = None,\n",
    "                alignment_history = False,\n",
    "                output_attention = False)\n",
    "            gcell = GNMTAttentionMultiCell(att_cell, decoder_cells)\n",
    "            \n",
    "            self.initial_state = tuple(\n",
    "                zs.clone(cell_state=es)\n",
    "                if isinstance(zs, tf.contrib.seq2seq.AttentionWrapperState) else es\n",
    "                for zs, es in zip(\n",
    "                    gcell.zero_state(batch_size * beam_width, dtype=tf.float32), encoder_state_tiled))\n",
    "            \n",
    "            predicting_decoder = tf.contrib.seq2seq.BeamSearchDecoder(\n",
    "                cell = gcell,\n",
    "                embedding = decoder_embeddings,\n",
    "                start_tokens = tf.tile(tf.constant([GO], dtype=tf.int32), [batch_size]),\n",
    "                end_token = EOS,\n",
    "                initial_state = self.initial_state,\n",
    "                beam_width = beam_width,\n",
    "                output_layer = to_dense,\n",
    "                length_penalty_weight = 0.0)\n",
    "            predicting_decoder_output, _, _ = tf.contrib.seq2seq.dynamic_decode(\n",
    "                decoder = predicting_decoder,\n",
    "                impute_finished = False,\n",
    "                maximum_iterations = 2 * tf.reduce_max(self.X_seq_len))\n",
    "            self.predicting_ids = predicting_decoder_output.predicted_ids[:, :, 0]\n",
    "            \n",
    "        masks = tf.sequence_mask(self.Y_seq_len, tf.reduce_max(self.Y_seq_len), dtype=tf.float32)\n",
    "        self.cost = tf.contrib.seq2seq.sequence_loss(logits = self.training_logits,\n",
    "                                                     targets = self.Y,\n",
    "                                                     weights = masks)\n",
    "        self.optimizer = tf.train.AdamOptimizer(learning_rate).minimize(self.cost)\n",
    "        y_t = tf.argmax(self.training_logits,axis=2)\n",
    "        y_t = tf.cast(y_t, tf.int32)\n",
    "        self.prediction = tf.boolean_mask(y_t, masks)\n",
    "        mask_label = tf.boolean_mask(self.Y, masks)\n",
    "        correct_pred = tf.equal(self.prediction, mask_label)\n",
    "        correct_index = tf.cast(correct_pred, tf.float32)\n",
    "        self.accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "size_layer = 512\n",
    "num_layers = 3\n",
    "learning_rate = 1e-3\n",
    "batch_size = 64\n",
    "epoch = 20"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /home/husein/.local/lib/python3.6/site-packages/tensorflow/python/util/deprecation.py:507: calling count_nonzero (from tensorflow.python.ops.math_ops) with axis is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "reduction_indices is deprecated, use axis instead\n",
      "WARNING:tensorflow:From <ipython-input-10-0ef5d475e26c>:64: GRUCell.__init__ (from tensorflow.python.ops.rnn_cell_impl) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "This class is equivalent as tf.keras.layers.GRUCell, and will be replaced by that in Tensorflow 2.0.\n",
      "WARNING:tensorflow:From <ipython-input-10-0ef5d475e26c>:90: bidirectional_dynamic_rnn (from tensorflow.python.ops.rnn) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use `keras.layers.Bidirectional(keras.layers.RNN(cell))`, which is equivalent to this API\n",
      "WARNING:tensorflow:From /home/husein/.local/lib/python3.6/site-packages/tensorflow/python/ops/rnn.py:464: dynamic_rnn (from tensorflow.python.ops.rnn) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use `keras.layers.RNN(cell)`, which is equivalent to this API\n",
      "WARNING:tensorflow:From /home/husein/.local/lib/python3.6/site-packages/tensorflow/python/ops/init_ops.py:1251: calling VarianceScaling.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Call initializer instance with the dtype argument instead of passing it to the constructor\n",
      "WARNING:tensorflow:From /home/husein/.local/lib/python3.6/site-packages/tensorflow/python/ops/rnn_cell_impl.py:564: calling Constant.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Call initializer instance with the dtype argument instead of passing it to the constructor\n",
      "WARNING:tensorflow:From /home/husein/.local/lib/python3.6/site-packages/tensorflow/python/ops/rnn_cell_impl.py:574: calling Zeros.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Call initializer instance with the dtype argument instead of passing it to the constructor\n",
      "WARNING:tensorflow:From /home/husein/.local/lib/python3.6/site-packages/tensorflow/python/ops/rnn.py:244: add_dispatch_support.<locals>.wrapper (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use tf.where in 2.0, which has the same broadcast rule as np.where\n",
      "WARNING:tensorflow:From <ipython-input-10-0ef5d475e26c>:93: MultiRNNCell.__init__ (from tensorflow.python.ops.rnn_cell_impl) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "This class is equivalent as tf.keras.layers.StackedRNNCells, and will be replaced by that in Tensorflow 2.0.\n",
      "WARNING:tensorflow:\n",
      "The TensorFlow contrib module will not be included in TensorFlow 2.0.\n",
      "For more information, please see:\n",
      "  * https://github.com/tensorflow/community/blob/master/rfcs/20180907-contrib-sunset.md\n",
      "  * https://github.com/tensorflow/addons\n",
      "  * https://github.com/tensorflow/io (for I/O related ops)\n",
      "If you depend on functionality not listed there, please file an issue.\n",
      "\n",
      "WARNING:tensorflow:From /home/husein/.local/lib/python3.6/site-packages/tensorflow/contrib/seq2seq/python/ops/beam_search_decoder.py:985: to_int64 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use `tf.cast` instead.\n"
     ]
    }
   ],
   "source": [
    "tf.reset_default_graph()\n",
    "sess = tf.InteractiveSession()\n",
    "model = Translator(size_layer, num_layers, size_layer,\n",
    "    len(dictionary_from), len(dictionary_to), learning_rate)\n",
    "sess.run(tf.global_variables_initializer())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "def str_idx(corpus, dic):\n",
    "    X = []\n",
    "    for i in corpus:\n",
    "        ints = []\n",
    "        for k in i.split():\n",
    "            ints.append(dic.get(k,UNK))\n",
    "        X.append(ints)\n",
    "    return X\n",
    "\n",
    "def pad_sentence_batch(sentence_batch, pad_int):\n",
    "    padded_seqs = []\n",
    "    seq_lens = []\n",
    "    max_sentence_len = max([len(sentence) for sentence in sentence_batch])\n",
    "    for sentence in sentence_batch:\n",
    "        padded_seqs.append(sentence + [pad_int] * (max_sentence_len - len(sentence)))\n",
    "        seq_lens.append(len(sentence))\n",
    "    return padded_seqs, seq_lens"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_X = str_idx(train_X, dictionary_from)\n",
    "test_X = str_idx(test_X, dictionary_from)\n",
    "train_Y = str_idx(train_Y, dictionary_to)\n",
    "test_Y = str_idx(test_Y, dictionary_to)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 20)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sess.run(model.predicting_ids, feed_dict = {model.X: [train_X[0]]}).shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [22:28<00:00,  1.54it/s, accuracy=0.272, cost=4.48] \n",
      "minibatch loop: 100%|██████████| 45/45 [00:11<00:00,  4.06it/s, accuracy=0.322, cost=4.05]\n",
      "minibatch loop:   0%|          | 0/2083 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 1, training avg loss 4.823276, training avg acc 0.227547\n",
      "epoch 1, testing avg loss 3.973857, testing avg acc 0.317220\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [22:25<00:00,  1.55it/s, accuracy=0.331, cost=3.66]\n",
      "minibatch loop: 100%|██████████| 45/45 [00:10<00:00,  4.13it/s, accuracy=0.345, cost=3.76]\n",
      "minibatch loop:   0%|          | 0/2083 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 2, training avg loss 3.645219, training avg acc 0.348635\n",
      "epoch 2, testing avg loss 3.687693, testing avg acc 0.349158\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [22:50<00:00,  1.52it/s, accuracy=0.404, cost=2.99] \n",
      "minibatch loop: 100%|██████████| 45/45 [00:11<00:00,  4.01it/s, accuracy=0.362, cost=3.7] \n",
      "minibatch loop:   0%|          | 0/2083 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 3, training avg loss 3.215255, training avg acc 0.392543\n",
      "epoch 3, testing avg loss 3.628983, testing avg acc 0.357726\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [21:34<00:00,  1.61it/s, accuracy=0.492, cost=2.46]\n",
      "minibatch loop: 100%|██████████| 45/45 [00:11<00:00,  4.08it/s, accuracy=0.35, cost=3.7]  \n",
      "minibatch loop:   0%|          | 0/2083 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 4, training avg loss 2.907694, training avg acc 0.428658\n",
      "epoch 4, testing avg loss 3.634721, testing avg acc 0.360200\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [21:22<00:00,  1.62it/s, accuracy=0.546, cost=2.06]\n",
      "minibatch loop: 100%|██████████| 45/45 [00:10<00:00,  4.29it/s, accuracy=0.345, cost=3.76]\n",
      "minibatch loop:   0%|          | 0/2083 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 5, training avg loss 2.668102, training avg acc 0.460165\n",
      "epoch 5, testing avg loss 3.687521, testing avg acc 0.360081\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [21:31<00:00,  1.61it/s, accuracy=0.611, cost=1.76]\n",
      "minibatch loop: 100%|██████████| 45/45 [00:10<00:00,  4.29it/s, accuracy=0.362, cost=3.78]\n",
      "minibatch loop:   0%|          | 0/2083 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 6, training avg loss 2.475425, training avg acc 0.487146\n",
      "epoch 6, testing avg loss 3.793251, testing avg acc 0.353237\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [21:54<00:00,  1.58it/s, accuracy=0.644, cost=1.55]\n",
      "minibatch loop: 100%|██████████| 45/45 [00:10<00:00,  4.30it/s, accuracy=0.35, cost=3.89] \n",
      "minibatch loop:   0%|          | 0/2083 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 7, training avg loss 2.319972, training avg acc 0.509522\n",
      "epoch 7, testing avg loss 3.871982, testing avg acc 0.352093\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [21:42<00:00,  1.60it/s, accuracy=0.665, cost=1.39] \n",
      "minibatch loop: 100%|██████████| 45/45 [00:10<00:00,  4.23it/s, accuracy=0.311, cost=4.07]\n",
      "minibatch loop:   0%|          | 0/2083 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 8, training avg loss 2.195564, training avg acc 0.527807\n",
      "epoch 8, testing avg loss 3.984652, testing avg acc 0.345306\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [21:37<00:00,  1.61it/s, accuracy=0.715, cost=1.29] \n",
      "minibatch loop: 100%|██████████| 45/45 [00:10<00:00,  4.30it/s, accuracy=0.316, cost=4.07]\n",
      "minibatch loop:   0%|          | 0/2083 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 9, training avg loss 2.098341, training avg acc 0.541759\n",
      "epoch 9, testing avg loss 4.050099, testing avg acc 0.340547\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [21:28<00:00,  1.62it/s, accuracy=0.701, cost=1.25] \n",
      "minibatch loop: 100%|██████████| 45/45 [00:10<00:00,  4.10it/s, accuracy=0.333, cost=4.12]\n",
      "minibatch loop:   0%|          | 0/2083 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 10, training avg loss 2.020236, training avg acc 0.553221\n",
      "epoch 10, testing avg loss 4.099510, testing avg acc 0.342090\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [21:46<00:00,  1.59it/s, accuracy=0.737, cost=1.11] \n",
      "minibatch loop: 100%|██████████| 45/45 [00:11<00:00,  4.06it/s, accuracy=0.333, cost=4.22]\n",
      "minibatch loop:   0%|          | 0/2083 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 11, training avg loss 1.956938, training avg acc 0.562348\n",
      "epoch 11, testing avg loss 4.171568, testing avg acc 0.338480\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [21:42<00:00,  1.60it/s, accuracy=0.746, cost=1.04] \n",
      "minibatch loop: 100%|██████████| 45/45 [00:11<00:00,  4.02it/s, accuracy=0.328, cost=4.31]\n",
      "minibatch loop:   0%|          | 0/2083 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 12, training avg loss 1.904061, training avg acc 0.569960\n",
      "epoch 12, testing avg loss 4.254099, testing avg acc 0.337221\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [21:38<00:00,  1.60it/s, accuracy=0.737, cost=1.03] \n",
      "minibatch loop: 100%|██████████| 45/45 [00:10<00:00,  4.10it/s, accuracy=0.339, cost=4.45]\n",
      "minibatch loop:   0%|          | 0/2083 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 13, training avg loss 1.861332, training avg acc 0.576394\n",
      "epoch 13, testing avg loss 4.339471, testing avg acc 0.335661\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [21:48<00:00,  1.59it/s, accuracy=0.757, cost=0.975]\n",
      "minibatch loop: 100%|██████████| 45/45 [00:10<00:00,  4.19it/s, accuracy=0.328, cost=4.44]\n",
      "minibatch loop:   0%|          | 0/2083 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 14, training avg loss 1.824426, training avg acc 0.581566\n",
      "epoch 14, testing avg loss 4.382103, testing avg acc 0.335848\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [21:51<00:00,  1.59it/s, accuracy=0.746, cost=1]    \n",
      "minibatch loop: 100%|██████████| 45/45 [00:10<00:00,  4.12it/s, accuracy=0.305, cost=4.54]\n",
      "minibatch loop:   0%|          | 0/2083 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 15, training avg loss 1.794062, training avg acc 0.585639\n",
      "epoch 15, testing avg loss 4.440851, testing avg acc 0.331752\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [21:47<00:00,  1.59it/s, accuracy=0.765, cost=0.934]\n",
      "minibatch loop: 100%|██████████| 45/45 [00:10<00:00,  4.15it/s, accuracy=0.299, cost=4.51]\n",
      "minibatch loop:   0%|          | 0/2083 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 16, training avg loss 1.769079, training avg acc 0.588865\n",
      "epoch 16, testing avg loss 4.444816, testing avg acc 0.332849\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [21:49<00:00,  1.59it/s, accuracy=0.752, cost=0.952]\n",
      "minibatch loop: 100%|██████████| 45/45 [00:10<00:00,  4.10it/s, accuracy=0.299, cost=4.47]\n",
      "minibatch loop:   0%|          | 0/2083 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 17, training avg loss 1.745167, training avg acc 0.592537\n",
      "epoch 17, testing avg loss 4.473411, testing avg acc 0.331796\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [21:51<00:00,  1.59it/s, accuracy=0.79, cost=0.884] \n",
      "minibatch loop: 100%|██████████| 45/45 [00:10<00:00,  4.12it/s, accuracy=0.294, cost=4.77]\n",
      "minibatch loop:   0%|          | 0/2083 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 18, training avg loss 1.726982, training avg acc 0.594760\n",
      "epoch 18, testing avg loss 4.521189, testing avg acc 0.332070\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [21:48<00:00,  1.59it/s, accuracy=0.774, cost=0.907]\n",
      "minibatch loop: 100%|██████████| 45/45 [00:10<00:00,  4.10it/s, accuracy=0.333, cost=4.4] \n",
      "minibatch loop:   0%|          | 0/2083 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 19, training avg loss 1.711785, training avg acc 0.596887\n",
      "epoch 19, testing avg loss 4.544723, testing avg acc 0.330962\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "minibatch loop: 100%|██████████| 2083/2083 [21:51<00:00,  1.59it/s, accuracy=0.762, cost=0.848]\n",
      "minibatch loop: 100%|██████████| 45/45 [00:10<00:00,  4.16it/s, accuracy=0.305, cost=4.73]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 20, training avg loss 1.695742, training avg acc 0.598858\n",
      "epoch 20, testing avg loss 4.600366, testing avg acc 0.330886\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "import tqdm\n",
    "\n",
    "for e in range(epoch):\n",
    "    pbar = tqdm.tqdm(\n",
    "        range(0, len(train_X), batch_size), desc = 'minibatch loop')\n",
    "    train_loss, train_acc, test_loss, test_acc = [], [], [], []\n",
    "    for i in pbar:\n",
    "        index = min(i + batch_size, len(train_X))\n",
    "        maxlen = max([len(s) for s in train_X[i : index] + train_Y[i : index]])\n",
    "        batch_x, seq_x = pad_sentence_batch(train_X[i : index], PAD)\n",
    "        batch_y, seq_y = pad_sentence_batch(train_Y[i : index], PAD)\n",
    "        feed = {model.X: batch_x,\n",
    "                model.Y: batch_y}\n",
    "        accuracy, loss, _ = sess.run([model.accuracy,model.cost,model.optimizer],\n",
    "                                    feed_dict = feed)\n",
    "        train_loss.append(loss)\n",
    "        train_acc.append(accuracy)\n",
    "        pbar.set_postfix(cost = loss, accuracy = accuracy)\n",
    "    \n",
    "    \n",
    "    pbar = tqdm.tqdm(\n",
    "        range(0, len(test_X), batch_size), desc = 'minibatch loop')\n",
    "    for i in pbar:\n",
    "        index = min(i + batch_size, len(test_X))\n",
    "        batch_x, seq_x = pad_sentence_batch(test_X[i : index], PAD)\n",
    "        batch_y, seq_y = pad_sentence_batch(test_Y[i : index], PAD)\n",
    "        feed = {model.X: batch_x,\n",
    "                model.Y: batch_y,}\n",
    "        accuracy, loss = sess.run([model.accuracy,model.cost],\n",
    "                                    feed_dict = feed)\n",
    "\n",
    "        test_loss.append(loss)\n",
    "        test_acc.append(accuracy)\n",
    "        pbar.set_postfix(cost = loss, accuracy = accuracy)\n",
    "    \n",
    "    print('epoch %d, training avg loss %f, training avg acc %f'%(e+1,\n",
    "                                                                 np.mean(train_loss),np.mean(train_acc)))\n",
    "    print('epoch %d, testing avg loss %f, testing avg acc %f'%(e+1,\n",
    "                                                              np.mean(test_loss),np.mean(test_acc)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "rev_dictionary_to = {int(k): v for k, v in rev_dictionary_to.items()}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(20, 198)"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_size = 20\n",
    "\n",
    "batch_x, seq_x = pad_sentence_batch(test_X[: test_size], PAD)\n",
    "batch_y, seq_y = pad_sentence_batch(test_Y[: test_size], PAD)\n",
    "feed = {model.X: batch_x}\n",
    "logits = sess.run(model.predicting_ids, feed_dict = feed)\n",
    "logits.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 predict: TED đẻ khác khác lâu khoảng <NUM> năm <NUM> khoảng lên năm <NUM> <NUM> , nói <NUM> khoảng năm <NUM> : khoảng <NUM> ở năm năm đã của : - <NUM> năm <NUM> <NUM> và năm <NUM> và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và\n",
      "0 actual: Làm sao tôi có thể trình bày trong <NUM> phút về sợi dây liên kết những người phụ nữ qua ba thế hệ , về việc làm thế nào những sợi dây mạnh mẽ đáng kinh ngạc ấy đã níu chặt lấy cuộc sống của một cô bé bốn tuổi co quắp với đứa em gái nhỏ của cô bé , với mẹ và bà trong suốt năm ngày đêm trên con thuyền nhỏ lênh đênh trên Biển Đông hơn <NUM> năm trước , những sợi dây liên kết đã níu lấy cuộc đời cô bé ấy và không bao giờ rời đi - - cô bé ấy giờ sống ở San Francisco và đang nói chuyện với các bạn hôm nay ?\n",
      "\n",
      "1 predict: Đây này loại là . . . . đấy đấy rồi . này . này . <NUM> . này . đang . . . . . . . . . . người . . . người . là . . . đấy . . người , được . . . này . . đó . . . đó . đã . . đó . . . đó đấy . . đó . . . đó đấy . . đó . . . đó đấy . . đó . . . đó . . đó . . . vậy . đó . . . đó . . . đó đấy . . đó . . . . . đó . đó . . . nó . . đó đó . . đó đó . . đó đã . . thế . đó . . . đó đã đó . đã . đó . . . . . . đã đó . đó . . . đó . đó . . . đó . . đó . . đó . . đó . . đó . . . đó . . đó . . . đó . đó . .\n",
      "1 actual: Câu chuyện này chưa kết thúc .\n",
      "\n",
      "2 predict: ngẫu ngẫu chống với để phơi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . đấy . . . . . . . . đấy . . . đó . đấy . . . đó . . . . đó . đó . . đó . đó đấy đấy đấy . . đó đấy . . này . này . này . . đó : . đó . : . : . đó . . . . đó : . thành này . . . đó : . . đó : . đó . người . đấy đấy . . đó này . . : . đó : . . . đấy . . thế . đó thứ . . đó : . đấy đó . . đó . đó đấy . . đó này . này . . đấy . . đó đấy đấy . . đấy . . . . . đó này .\n",
      "2 actual: Nó là một trò chơi ghép hình vẫn đang được xếp .\n",
      "\n",
      "3 predict: Tôi về với về một một một một từng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
      "3 actual: Hãy để tôi kể cho các bạn về vài mảnh ghép nhé .\n",
      "\n",
      "4 predict: cái viên : : là : sống . người . người . người . người . nam cư . người : . đất đầu sử . phi . đất . đất . đất đầu quen . người : . đất . đất công . đất . nam : . người . người . người : tiên . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người , cư . . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người . người .\n",
      "4 actual: Hãy tưởng tượng mảnh đầu tiên : một người đàn ông đốt cháy sự nghiệp cả đời mình .\n",
      "\n",
      "5 predict: một là là , một qua một với , mình và xe sắt và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và\n",
      "5 actual: Ông là nhà thơ , nhà viết kịch , một người mà cả cuộc đời chênh vênh trên tia hi vọng duy nhất rằng đất nước ông sẽ độc lập tự do .\n",
      "\n",
      "6 predict: khi viên ấy tay đã sau ra của đầu đã trọn đầu đầu đầu thắng mất ấy người . ấy mới đã . . thật . . . . . . . . . . . . . . . . . . . . đấy . . người . người . con thực hiện . . . . . . . . . . . . . . . ấy . ấy . . . . ấy . con . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . đó đó đầu đầu . đã . . . đấy đấy đấy nhỉ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ấy đấy ganh . đó . . . . . . . . . . .\n",
      "6 actual: Hãy tưởng tượng ông , một người cộng sản tiến vào , đối diện sự thật rằng cả cuộc đời ông đã phí hoài .\n",
      "\n",
      "7 predict: lúc về rồi anh nó bạn nhé anh . anh đó . . anh . anh . bạn . anh đó , , . . là . . . đó đó \" . anh phút này . anh . anh anh <NUM> hả . anh . anh ra này đó . . anh . anh đó . đó . đó . đó đấy . . anh đó cụm này đó . . đó . đó . đó . đó đó đó . đó rồi . đó đó đó . đó . đó rồi . đó . đó . đó . đó đó đó . đó đó . đó . đó đó đó đấy vậy \" vậy \" . mà đó đấy . này . này . này . này . này . này . này . này . này . này . này . này . này . này . này . này . này . ạ đó . đấy đấy đấy rồi . đó là nó đó điều . đó đó . đó rồi . . đó đó . đó đấy . . đó đó này . đó đó . đó . đó . đó . đó\n",
      "7 actual: Ngôn từ , qua bao năm tháng là bạn đồng hành với ông , giờ quay ra chế giễu ông .\n",
      "\n",
      "8 predict: anh đi . . . . . . . đó đó . đó . . đó . đó . đó đó . . . đó . đó . . đó . . đó . đó . . đó đó . . đó điều . . . đó . . đó đó đó : . thế nó nó . đó : . đó này ấy . này . thế này . . . đó này . : . Rồi này . . : . đó này . . : . đó : . . vậy . Rồi xong . Rồi . . Rồi . Rồi và và và và và và và và . . Rồi xong và và và và và và và và và . . Rồi xong và và và và và và và và và và và và . Rồi . Rồi và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và và . . Rồi . Rồi và đó . : . sau ra đổi . .\n",
      "8 actual: Ông rút lui vào yên lặng .\n",
      "\n",
      "9 predict: đã sau đã . đã . . mươi . . người . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Do . Thực Thực . đã đó . . . . đã đã , thống . . . . . . , hoạ , . . hoạ đó nhận . . . . . . . . . đấy . . . . . Đất đó . . . . đấy . . đấy . . đó đó . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
      "9 actual: Ông qua đời , bị lịch sử quật ngã .\n",
      "\n",
      "10 predict: ông danh . ác . tôi tôi của . tôi . tôi tôi của . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi của . . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi\n",
      "10 actual: Ông là ông của tôi .\n",
      "\n",
      "11 predict: anh sống anh anh . anh đó ! anh . anh . anh ấy . . . . . . . . . . . . . . đấy anh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ấy . . . . . . . . . . . . . . . . . . . . . ấy . . . . . . ấy . . . ấy . ấy . ấy . ấy . ấy . ấy . ấy .\n",
      "11 actual: Tôi chưa bao giờ gặp ông ngoài đời .\n",
      "\n",
      "12 predict: cả em búa thì của . . ấy . cháu . . người . người . đã ấy . . . . . . . . . . . . . . . . . . . . . . . . . . ấy . . . . . . . . . ấy . . . . . . . . . . . ấy . . . . . . . . . đã ấy . ấy . . . . . . ấy . . . . . . . . . . ấy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . đó ấy . đã . ấy . đã . đó . đó . đó . đó . đó . đó . đó đã đã . đã . đã . . đó . đấy . đã . . . . đã . . đó . . đó là . . . . . . .\n",
      "12 actual: Nhưng cuộc đời ta nhiều hơn những gì ta lưu trong kí ức nhiều .\n",
      "\n",
      "13 predict: \" của sự của đời cuộc của . chị . tôi . . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . của . . . . . . . đời của . . . . . . . . . . . . . . . . tôi đấy . . tôi . . tôi . tôi . . tôi tôi tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . thứ . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . tôi . thứ . bà tôi . tôi . tôi . tôi . tôi , tính . . tôi . tôi . bà tôi sắp . . tôi .\n",
      "13 actual: Bà tôi chưa bao giờ cho phép tôi quên cuộc đời của ông .\n",
      "\n",
      "14 predict: Văn của của sự , nói , , , , , , , , , , , và , , , , và và và , , , , , và và , và , , , , và , , , và , , , và , , , và , , , và , , , và , , , và , , , và , , , và , , , và , , , và , , , và và , và và , , , , , , , , , , , và , , , , , , , , , , , , , , , , , , , , , , , , , , , , và , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,\n",
      "14 actual: Nhiệm vụ của tôi là không để cuộc đời ấy qua trong vô vọng , và bài học của tôi là nhận ra rằng , vâng , lịch sử đã cố quật ngã chúng tôi , nhưng chúng tôi đã chịu đựng được .\n",
      "\n",
      "15 predict: Tốc tiếp sắp đang là dương dương trong của quang . bên . . . . . mảnh . mảnh nhỏ . . . . . . mảnh nhỏ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . con . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . con . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
      "15 actual: Mảnh ghép tiếp theo của tấm hình là một con thuyền trong sớm hoàng hôn lặng lẽ trườn ra biển .\n",
      "\n",
      "16 predict: Cha em : , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , với hai , <NUM> <NUM> : hai hai hai hai . em : . <NUM> : , được , . . , đất . <NUM> . <NUM> đấy . . . . . . . . . . . . . . . . . . . . đấy . . . . đấy . . . . đấy . . . . . đấy . . . . . đấy . . . . . đấy . . . . . đấy . . . . . đấy . . . . . đấy . . . . . đấy . . . . . đấy . . . . . đấy . . . . . đấy . . . đấy . . . đấy . . . . . . đấy . . . đấy . . . . .\n",
      "16 actual: Mẹ tôi , Mai , mới <NUM> tuổi khi ba của mẹ mất - - đã lập gia đình , một cuộc hôn nhân sắp đặt trước , đã có hai cô con gái nhỏ .\n",
      "\n",
      "17 predict: Krosoczka hôn đã , , mới một một một một một một một một một một một một một một một một một một một một một một một một một một một một một một một một một một . : : : : : : là : gặp : đặt sống nước mà mình . bà : : : : : : : : : : : : : : : : : : : : là : : : : là mới : : : : : : : là : : là mới : : : của : : : : của : của : : : là : : là : : : là : . người mà người . người : đặt . : . người : : : : : : : : : : : : : : : : : : : là mới : : : : : : : : : : : : : : : : : : : : : : : : : : : : : là : : mới : : : : : : là mới : mới : :\n",
      "17 actual: Với mẹ , cuộc đời cô đọng vào nhiệm vụ duy nhất : để gia đình mẹ trốn thoát và bắt đầu cuộc sống mới ở Úc .\n",
      "\n",
      "18 predict: ban nó là vẫn vẫn vẫn . . cả . đó . đó là nó \" . là nó nó nó nó nó nó . . đó đó nó đó . . bà đó đó \" . . . . . đó đó . đó . đó . đó . . nó đó đó \" . đó đó . này . <NUM> . . . đó đó \" . . này đó . . đó . đó . đó . đó . đó . đó đó đó . đó đó : . đó đó . đó đó : . đấy . . nó đó đó . . đó đó . đó đó \" . . . đấy . . đó đó \" . . . . . đấy . . đó đó \" . . đấy . . đó đó . đó . đó . đó . đó . đó đó đó . đó đó sông . đó đó nó . đó đó : . đấy đó . . đó . đó . . . đó sông . đó đó đó . đó đó đã . đó đó đó . . đã . đó đấy đó . đã\n",
      "18 actual: Mẹ không bao giờ chấp nhận được là mẹ sẽ không thành công .\n",
      "\n",
      "19 predict: <NUM> sau cạnh , , , rằng , lại , , rằng là ngựa <NUM> này là cứng cứng cứng . thợ . . cầu . Muhammad . Động . rồng . thợ . . ấy . đâm . . . . . . . . . . . . . . . . . . trời . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
      "19 actual: Thế là sau bốn năm , một trường thiên đằng đẵng hơn cả trong truyện , một chiếc thuyền trườn ra biển nguỵ trang là thuyền đánh cá .\n",
      "\n"
     ]
    }
   ],
   "source": [
    "rejected = ['PAD', 'EOS', 'UNK', 'GO']\n",
    "\n",
    "for i in range(test_size):\n",
    "    predict = [rev_dictionary_to[i] for i in logits[i] if rev_dictionary_to[i] not in rejected]\n",
    "    actual = [rev_dictionary_to[i] for i in batch_y[i] if rev_dictionary_to[i] not in rejected]\n",
    "    print(i, 'predict:', ' '.join(predict))\n",
    "    print(i, 'actual:', ' '.join(actual))\n",
    "    print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
